package ru.spbau.krasko.phonelock.dynamic;

import java.util.Vector;

import net.rim.device.api.math.Fixed32;
import net.rim.device.api.system.ApplicationDescriptor;
import net.rim.device.api.system.ApplicationManager;
import net.rim.device.api.system.ApplicationManagerException;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Graphics;
import ru.spbau.krasko.phonelock.main.LockScreen;
import ru.spbau.krasko.phonelock.settings.Settings;
import ru.spbau.krasko.phonelock.utils.Constants;

public class DynamicIcon extends DynamicField {

	private final Bitmap bitmap;
	private final int width;
	private final int height;

	private final static int Y_OFFSET = Constants.SCREEN_H / 5;

	static Vector[] icons;

	private String name;
	private ApplicationDescriptor descriptor;

	public DynamicIcon(final ApplicationDescriptor descriptor) {
		super(0, 0);
		if (descriptor.getLocalizedName().equals("Phone Lock")) {
			this.name = "Unlock phone";
		} else {
			this.name = descriptor.getLocalizedName();
		}
		this.descriptor = descriptor;
		EncodedImage icon = descriptor.getEncodedIcon();
		if (icon != null && icon.getWidth() > 30 && icon.getHeight() > 30) {
			int w = icon.getWidth();
			int h = icon.getHeight();
			int k = 156 * Math.max(w, h);
			this.bitmap = icon.scaleImage32(Fixed32.tenThouToFP(k),
					Fixed32.tenThouToFP(k)).getBitmap();
		} else {
			this.bitmap = Bitmap.getPredefinedBitmap(Bitmap.QUESTION);			
		}
		width = bitmap.getWidth();
		height = bitmap.getHeight();
	}

	public static void restoreAll() {
		icons = Settings.getDescriptors();
		new AppChooser();
		for (int i = 0; i < 2; ++i) {
			for (int j = 0; j < icons[i].size(); ++j) {
				new DynamicIcon((ApplicationDescriptor) icons[i].elementAt(j));
			}
		}
		recalcOrigins();
		allReturnToOrigins(true, null);
	}

	public static void removeAll() {
		Settings.serializeDescriptors();
		destroyAll();
		icons = new Vector[0];
	}

	public void setDesiredPos(int x, int y) {
		int yAlign = y < (Constants.SCREEN_H / 2) ? 0 : 1;

		int index = x * icons[yAlign].size() / Constants.SCREEN_W;
		if (index >= icons[yAlign].size()
				|| icons[yAlign].elementAt(index) != descriptor) {
			// moved truly
			icons[0].removeElement(descriptor);
			icons[1].removeElement(descriptor);
			index = x * (icons[yAlign].size() + 1) / Constants.SCREEN_W;
			icons[yAlign].insertElementAt(descriptor, index);
			recalcOrigins();
			allReturnToOrigins(false, this);
		}
		super.setDesiredPos(x, y);
	}

	public void paint(Graphics g) {
		if (bitmap != null)
			g.drawBitmap(getRealX() - width / 2, getRealY() - height / 2,
					width, height, bitmap, 0, 0);
		g.setColor(0x00BBBBBB);

		int offset = g.getFont().getBounds(name) / 2;
		g.drawText(name, getRealX() - offset, getRealY() + height / 2,
				DrawStyle.TOP);
	}

	private static void recalcOrigins() {
		for (int i = 0; i < instances.size(); ++i) {
			if (instances.elementAt(i) instanceof DynamicIcon) {
				DynamicIcon icon = ((DynamicIcon) instances.elementAt(i));
				ApplicationDescriptor d = icon.descriptor;
				int index = icons[0].indexOf(d);
				if (index != -1) {
					icon.setOriginalPos(
							Constants.SCREEN_W * index / icons[0].size()
									+ Constants.SCREEN_W / icons[0].size() / 2,
							Y_OFFSET);
				} else {
					index = icons[1].indexOf(d);
					if (index == -1)
						continue;
					icon.setOriginalPos(
							Constants.SCREEN_W * index / icons[1].size()
									+ Constants.SCREEN_W / icons[1].size() / 2,
							Constants.SCREEN_H - Y_OFFSET);
				}
			}
		}
	}

	public void initInteraction(DynamicField df) {
		df.interact(this);
	}

	public void performAction() {
		LockScreen.INSTANCE.unlock();
		if (!ApplicationDescriptor.currentApplicationDescriptor().equals(
				descriptor)) {
			try {
				ApplicationManager.getApplicationManager().runApplication(
						descriptor);
			} catch (ApplicationManagerException e) {
				System.out.println(e.getMessage());
			}
		}
	}
}
